#include "temp.h"
#include "gpio.h"
#include "stm32f1xx_hal.h"

#include "main.h"

void Delay_DS18B20(int num)
{
	uint x;
	for( ; num>0; num--)
	{
		for(x=100; x>0; x--);
	}
}
/*******************************************************************************
* 函 数 名         : Delay1ms
* 函数功能		   : 延时函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Delay1ms(uint y)
{
	HAL_Delay(y);
	// uint x;
	// for( ; y>0; y--)
	// {
	// 	for(x=110; x>0; x--);
	// }
}
/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能		   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1，失败返回0
*******************************************************************************/

uchar Ds18b20Init()
{
	unsigned char x=0;
  HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 1);         //DQ复位
  Delay_DS18B20(8);    //稍做延时
  HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 0);         //单片机将DQ拉低
  Delay_DS18B20(80);   //精确延时，大于480us
  HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 1);          //拉高总线
  Delay_DS18B20(14);
  x=HAL_GPIO_ReadPin((GPIO_TypeDef *)GPIOB, 
                   (uint16_t) GPIO_PIN_12);           //稍做
	return x;//初始化成功
}

/*******************************************************************************
* 函 数 名         : Ds18b20WriteByte
* 函数功能		   : 向18B20写入一个字节
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void Ds18b20WriteByte(uchar dat)
{
	unsigned char i=0;
  for (i=8; i>0; i--)
  {
    HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 0);
    HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) dat&0x01);
    Delay_DS18B20(5);
    HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 1);
    dat>>=1;
  }
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadByte
* 函数功能		   : 读取一个字节
* 输    入         : com
* 输    出         : 无
*******************************************************************************/


uchar Ds18b20ReadByte()
{
	unsigned char i=0;
  unsigned char dat = 0;
  uint8_t DSPORT;
  for (i=8;i>0;i--)
  {
    HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 0);     // 给脉冲信号
	DSPORT=HAL_GPIO_ReadPin((GPIO_TypeDef *)GPIOB, 
                   (uint16_t) GPIO_PIN_12); 
    dat>>=1;
    HAL_GPIO_WritePin((GPIO_TypeDef *)GPIOB, 
                        (uint16_t) GPIO_PIN_12, 
                        (GPIO_PinState) 1);     // 给脉冲信号
    DSPORT=HAL_GPIO_ReadPin((GPIO_TypeDef *)GPIOB, 
                   (uint16_t) GPIO_PIN_12); 
	if(DSPORT)
    dat|=0x80;
    Delay_DS18B20(4);
  }
  return(dat);
}
/*******************************************************************************
* 函 数 名         : Ds18b20ChangTemp
* 函数功能		   : 让18b20开始转换温度
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void  Ds18b20ChangTemp()
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
	Ds18b20WriteByte(0x44);	    //温度转换命令
//	Delay1ms(100);	//等待转换成功，而如果你是一直刷着的话，就不用这个延时了
   
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTempCom
* 函数功能		   : 发送读取温度命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void  Ds18b20ReadTempCom()
{	

	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTemp
* 函数功能		   : 读取温度
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

int Ds18b20ReadTemp()
{
	int temp = 0;
	uchar tmh, tml;

	Ds18b20ChangTemp();			 	//先写入转换命令
	Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令
	tml = Ds18b20ReadByte();		//读取温度值共16位，先读低字节
	tmh = Ds18b20ReadByte();		//再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}


int GetTemp(void)
{
	int temp;
	float tp; 
	
	temp = Ds18b20ReadTemp();
	if(temp<= 0)				    //当温度值为负数
  {
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;	
		// Uart_SendString("Overrate!\r\n");    //超过量程
  }
 	else
	{			
		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
		//如果温度是正的那么，那么正数的原码就是补码它本身
		temp=tp*0.0625*100+0.5;	
		//留两个小数点就*100，+0.5是四舍五入，因为C语言浮点数转换为整型的时候把小数点
		//后面的数自动去掉，不管是否大于0.5，而+0.5之后大于0.5的就是进1了，小于0.5的就
		//算加上0.5，还是在小数点后面。
	}
		 
	return temp;
}

